using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Silverlight.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
using SLNGP.Core.Individuals;
using SLNGP.Core.Test;

namespace SLNGP.Test.CoreTests.Individuals
{
    [TestClass]
    [Tag("Generation")]
    public class Generation_Test : UnitTestBase<IGeneration, Generation>
    {
        #region UnitTestBase methods
        [ClassInitialize]
        public static void ClassInitialize(TestContext testContext)
        {
            UnitTestBase<IGeneration, Generation>.ClassInitialize(testContext);
        }

        [ClassCleanup]
        public static void ClassCleanup()
        {
            UnitTestBase<IGeneration, Generation>.ClassCleanup();
        }

        [TestInitialize]
        public override void TestInitialize()
        {
            base.TestInitialize();
        }

        [TestCleanup]
        public override void TestCleanup()
        {
            base.TestCleanup();
        }
        #endregion UnitTestBase methods

        [TestMethod]
        public void WithMockIndividual_Contains_ReturnsTrue()
        {
            // state - WithMockIndividual
            var mock = mocks.DynamicMock<IIndividual>();
            curElement.Add(mock);

            using (mocks.Record())
                Expect.Call(mock.GetStringDisplay()).Return(TestStrings[0]);

            // action - Contains
            var result = curElement.ContainsIndividualWithSameGenome(mock);

            // Expectation - ReturnsTrue
            Assert.IsTrue(result);
        }

        [TestMethod]
        public void WithMockIndividualToString_Contains_ReturnsTrue()
        {
            // state - WithMockIndividualToString
            var mock = mocks.StrictMock<IIndividual>();
            curElement.Add(mock);

            using(mocks.Record())
                Expect.Call(mock.GetStringDisplay()).Return(TestStrings[0]).Repeat.Twice();

            // action - Contains
            var result = curElement.ContainsIndividualWithSameGenome(mock);

            // Expectation - ReturnsTrue
            Assert.IsTrue(result);
            mocks.VerifyAll();
        }

        [TestMethod]
        public void TwoDifferentMockIndividualsWithOneInGeneration_ContainsTheOther_ReturnsFalse()
        {
            // state - WithMockIndividualToString
            var mock1 = mocks.DynamicMock<IIndividual>();
            var mock2 = mocks.DynamicMock<IIndividual>();
            curElement.Add(mock1);

            using (mocks.Record())
            {
                Expect.Call(mock1.GetStringDisplay()).Return(TestStrings[0]);
                Expect.Call(mock2.GetStringDisplay()).Return(TestStrings[1]);
            }

            // action - Contains
            var result = curElement.ContainsIndividualWithSameGenome(mock2);

            // Expectation - ReturnsTrue
            Assert.IsTrue(result == false);
            mocks.VerifyAll();
        }

        [TestMethod]
        public void GenerationWithMockIndividual_CallUniqueAdd_ReturnsFalseAndElementIsNotAddedTwice()
        {
            // state - GenerationWithMockIndividual
            var mock = mocks.DynamicMock<IIndividual>();
            curElement.Add(mock);

            using (mocks.Record())
                Expect.Call(mock.GetStringDisplay()).Return(TestStrings[0]);

            // action - CallUniqueAdd
            var result = curElement.TryAddUnique(mock);

            // Expectation - ReturnsFalseAndElementIsNotAddedTwice
            Assert.IsTrue(curElement.Count == 1);
            Assert.IsTrue(result == false);
        }

        [TestMethod]
        public void EmptyGeneration_CallUniqueAdd_ReturnsTrueAndElementIsAdded()
        {
            // state - GenerationWithMockIndividual
            var mock = mocks.DynamicMock<IIndividual>();

            using (mocks.Record())
                Expect.Call(mock.GetStringDisplay()).Return(TestStrings[0]);

            // action - CallUniqueAdd
            var result = curElement.TryAddUnique(mock);

            // Expectation - ReturnsFalseAndElementIsNotAddedTwice
            Assert.IsTrue(curElement.Count == 1);
            Assert.IsTrue(curElement.Contains(mock));
            Assert.IsTrue(result == true);
        }
    }
}
